<?php

  // ** function.php **
  // 
  // 內容：常用自訂函數
  // 1. 對 browser 指定使用 UTF-8 編碼
  // 2. 自動取得院內網連線使用的 cookie array (即 $cka)
  //    只要在自訂函數內使用 [global $cka;] 命令即可使用 $cka
  // 3. 取得 DOM 物件：[$dom=ntuhDom($url);]
  // 4. 若本來是使用 putty 新編檔案或是從 windows 系統上傳
  //    則所有中文字串請用 i 函數處理過 (因其為 BIG5 編碼)
  //    或在 shell 下用 [iconv -f big5 -t utf-8 inputfile > outputfile] 轉換
  //    再用 pietty 編輯 (pietty 本來就是預設 UTF-8 處理)
  //    所有中文字串處理請使用 mbstring functions
  //    (iconv 轉換某些中文字元會有問題)
  // 5. Domain name: intra.mc.ntu.edu.tw 可能會被取消
  //    所有連結換成 172.16.38.1

  header('Content-Type: text/html; charset=utf-8'); //指定頁面使用 UTF-8 編碼
  mb_substitute_character("none");
  require_once "pwd.php"; // 1. 取得登入網址 for get_session
                          // 2. 資料庫 db username & passowrd
                          // 3. Portal username & password

  function i($string){ // Convert string encoding from BIG5 to UTF-8, unnecessory if using pietty.
    return mb_convert_encoding($string,"utf-8","big5");
  }
  
  function ConvDate($date,$delimiter){ //轉換日期格式：民國 -> 西元, $delimiter為分隔字元, 如 yy.mm.dd -> yyyy.mm.dd
    $date_split=explode($delimiter,$date);
    $date_split[0]=$date_split[0]+1911;
    return implode($delimiter,$date_split);
  }

  function get_dbh(){ // 連線到 MySQL 並回傳 PDO DB handle 以供 query 或 exec
      global $dsn,$user,$pwd;
      $dbh=new PDO($dsn,$user,$pwd);
      $charset="set names 'utf8'";
      $dbh->query($charset);
      return $dbh;
  }

  function get_session(){ // 回傳 $cka (cookie array for class HttpRequest)
    global $url;
    $r=new HttpRequest($url['intra']);
    $r->send();
    $ck=$r->getResponseHeader();
    $ck=split("=",$ck['Set-Cookie']);
    $ck[1]=explode(";",$ck[1]);
    $ck[1]=$ck[1][0];
    $ck0=$ck[0];
    $ck1=$ck[1];
    $cka=array($ck0=>$ck1,path=>'/');
    return $cka;
  }

  function ntuhintra($url){ //登入院內網路後回傳 utf-8 編碼的 $url 內容 (HTML)
    global $cka;
    mb_substitute_character("none");
    $r2=new HttpRequest($url);
    $r2->enableCookies();
    $r2->setCookies($cka);
    $r2->send();
    $rsp=$r2->getResponseBody();
    $rsp=str_replace("charset=big5","charset=utf-8", $rsp);
    $rsp2=mb_convert_encoding($rsp,'utf-8','big5');
    return $rsp2;
  }

  function ntuhDom($url){ //回傳 $url 的 DOM object $dom
    global $cka;
    $raw=ntuhintra($url);
    $dom=new DOMDocument;
    $dom->preserveWhiteSpace=FALSE;
    @$dom->loadHTML($raw);
    return $dom;
  }

  // 取得 portal 登入頁面的 __VIEWSTATE 及 __EVENTVALIDATION 變數 ($viewstate, $eventvalidation)
  // 每個頁面幾乎都有，可考慮寫成另一個 function
  function viewstate($url){
    //global $url;
    $dom=new DOMDocument;
    $dom->preserveWhiteSpace=FALSE;
    @$dom->loadHTMLFile($url);
    foreach($dom->getElementsByTagName('input') as $element){
      if($element->getAttribute('name')=='__VIEWSTATE')
        $viewstate=$element->getAttribute('value');
      if($element->getAttribute('name')=='__EVENTVALIDATION'){
        $eventvalidation=$element->getAttribute('value');
        break;
      }
    }
    $hidden=array();
    $hidden['viewstate']=$viewstate;
    $hidden['eventvalidation']=$eventvalidation;
    return $hidden;
  }

  function portalsession(){
    global $url;
    $hidden=viewstate($url['portal']['home']);
    // 登入 portal 後取得 ASP SESSIONID ($sessionid)
    // 在 URL 後加上 ?SESSION=$sessionid 即可正常連線
    // 若 __VIEWSTATE 只和 IP 有關的話可考慮 設為 constant 即可
    $r=new HttpRequest($url['portal']['home']);
    $r->setMethod(HTTP_METH_POST);
    $data=array('txtUserID'=>$url['portal']['user'],'txtPass'=>md5($url['portal']['pass']),'__EVENTTARGET'=>'','__EVENTARGUMENT'=>'','__VIEWSTATE'=>$hidden['viewstate'],'__EVENTVALIDATION'=>$hidden['eventvalidation'],'rdblQuickMenu'=>'H','imgBtnSubmitNew.x'=>'0','imgBtnSubmitNew.y'=>'0');
    $r->addPostFields($data);
    $r->send();
    $header=$r->getResponseHeader();
    $session=explode('SESSION=',$header['Location']);
    $sessionid=$session[1];
    return $sessionid;
  }

  function LabItemSearch($id,$url,$item){ // 找出 $url 中第一筆 serum creatinine 值
    global $cka;
    $labs=array();
    $dom=ntuhDom($url);
    foreach($dom->getElementsByTagName('td') as $element){
      if($element->firstChild->nodeName=='hr'){
        $labs[]='hr';
      }
      if(trim($element->textContent)==$item){
        $value=trim($element->nextSibling->nextSibling->childNodes->item(2)->textContent);
        $labs[]=$value;
      }
      if(substr_count($element->textContent,'BLOOD')>=1){
	if(trim($element->childNodes->item(0)->textContent)==NULL){
	  $labs[]=trim($element->childNodes->item(1)->textContent);
	}else{
	  $labs[]=trim($element->childNodes->item(0)->textContent);
	}
      }  
    }
    for($i=0;$i<=count($labs);$i++){
      if(substr_count($labs[$i],$item)>=1&&$labs[$i-1]!='hr'){
	return ConvDate(mb_substr($labs[$i-1],3,8,'utf-8'),'.').' '.$labs[$i];
      }
    }
    return NULL;
  }
  
  function getLabCaseno($id,$item){
    //取得某$id一年內所有lab data的caseno，以陣列回傳; 若lab首頁就有serum creatinine則馬上回傳
    global $cka;
    $url='http://172.16.38.1/DigReport/Lab/NewQuery.asp?chartno='.$id;
    $caseno=array();
    $quick=LabItemSearch($id,$url,$item);
    if($quick!=NULL) return $quick;
    $dom=ntuhDom($url);
    foreach($dom->getElementsByTagName('a') as $a){
      if(mb_substr_count($a->getAttribute('href'),'caseno')>=1){
	$y=ageOI(ConvDate(trim($a->parentNode->parentNode->childNodes->item(6)->nodeValue),'.'),date('Y.m.d',time()));
	if($y['y']<1) $caseno[]=trim($a->nodeValue);
      }
    }
    if(!empty($caseno)) return $caseno;
  }

  function getLabDept($id,$casenos,$item){ //取得各筆 lab $caseno 中最新一筆一年內抽血 CRE 值
    global $cka;
    $cres=array();
    foreach($casenos as $caseno){
      $url='http://172.16.38.1/DigReport/Lab/QueryDept.asp?caseno='.$caseno.'&chartno='.$id;
      $dom=ntuhDom($url);
      foreach($dom->getElementsByTagName('a') as $a){
        if(mb_substr_count($a->getAttribute('href'),'maxReleaseDate','utf-8')>=1){
          $cre=LabItemSearch($id,htmlspecialchars_decode('http://172.16.38.1'.mb_substr($a->getAttribute('href'),5,strlen($a->getAttribute('href'))-5,'utf-8')),$item);
          if($cre!=NULL){
            $cres[]=$cre;
            continue;
          }
        }
      }
      if(!empty($cres)){
        rsort($cres);
        $date=substr($cres[0],0,10);
        $intv=ageOI($date,date('Y.m.d',time()));
        if($intv['y']>=1){
          return NULL;
        }else return $cres[0];
      }
    }
    return NULL;
  }

  function getName($id){ // 回傳 $name 陣列，其中含有 utf-8 編碼的 'name', 'birthdate' (yyyy.mm.dd), 'gender' (M/F); $id 為病歷號
    mb_substitute_character("none");
    $name=array();
    //$m='男';
    //$f='女';
    // error id = 5386992; strange big5 character in name
    $url='http://172.16.38.1/DigReport/Lab/menu.asp?chartno='.$id;
    $dom=ntuhDom($url);
    foreach($dom->getElementsByTagName('font') as $font){
      if(trim($font->nodeValue)=='姓名:'){
	  $name['name']=trim($font->nextSibling->nodeValue);
	  $birthdate=trim($font->parentNode->childNodes->item(5)->nodeValue);
	  $birthdate=mb_substr($birthdate,3,8,'utf-8');
	  $name['birthdate']=ConvDate($birthdate,'.');
	  $gender=trim($font->parentNode->childNodes->item(3)->nodeValue);
	  switch ($gender) {       //reduce unnecessary "if"
	    case "男":
		  $name['gender']='M';
		  break;
		case "女":
		  $name['gender']='F';
		  break;
	  }	
//	  if($gender==$m) $name['gender']='M';
//	  if($gender==$f) $name['gender']='F';
      }
      return $name;
    }
  }

  function PathList($chartno){   //病理報告資料表
  /*input: $chartno 
      *output:$path[] array with key=       
         'PathCode'
         'ChartNo' 
         'ChineseName'
         'Sex' => string 'F'
         'Birthday' => string ' 0390126'
         'SpecimenCode' => string 'b '
         'SpecimenGetDate' => string '092/02/18'
         'ReportDate' => string '092/02/20'
         'VSIdNo' => string 'DTPAT002  '
         'RIdNo' => string 'DTPAT055  '
         'ExamDr' => string 'DTPAT002  ' 
         'InCharge' => string 'Y.H.Lin     ' 
    */
    $path=array();
    $url='http://172.16.38.1/DigReport/Lab/PathExam.asp?chartno='.$chartno;
    $dom=ntuhDom($url);

    foreach ($dom->getElementsByTagName('a') as $a){
      $completeURL='http://172.16.38.1/DigReport/Lab/'.$a->getAttribute('href');  
        /*將每一次的病理報告聯結轉換為絕對路徑*/
      $query=parse_url($completeURL, PHP_URL_QUERY);    
        /*將$path_url中query的部分以array儲存*/
      parse_str($query,$path[]);   
        /*將 $query內容parse成$path array*/  
    }
        
    return $path;
  }

  function PathCodes($id){
    $path=array();
    $url='http://172.16.38.1/DigReport/Lab/PathExam.asp?chartno='.$id;
    $dom=ntuhDom($url);
    foreach($dom->getElementsByTagName('a') as $a){
      if(mb_substr_count($a->getAttribute('href'),'PathCode')>=1){
        $path[]=$a->textContent;
      }
    }
    return $path;
  }

  function RadList($chartno,$year,$type){ 
  /*
   * parameter: 
   * $chartno= 病歷號
   * $year=時間為多少"年"內的影像檢查
   * $type=ALL為全部
   * return=rad array 
  */
    $rad=array();
    $url='http://172.16.38.1/DigReport/Xray/XrayExam.asp?chartno='.$chartno.'&durnum='.$year.'&dattype=Y&reptype='.$type;
    $dom=ntuhDom($url);

    foreach ($dom->getElementsByTagName('a') as $a){
      $completeURL='http://172.16.38.1/DigReport/Xray/'.$a->getAttribute('href');  /*將每一次的報告聯結轉換為絕對路徑*/
      $query=parse_url($completeURL, PHP_URL_QUERY);    /*將$completeURL中query的部分以array儲存*/
      parse_str($query,$rad[]);   /*將 $query內容parse成$rad array*/  
    }
  return $rad;
  }
  
  function getPath($id){ 
    /* 查詢第$i次病理檢查碼之報告內容, 回傳 $report[$i][]，內含：
         [$j]['organ'] ($j starts from 0)
         [$j]['diagnosis']
         ['main'], ['ps'], ['SpecimenGetDate'] */
    $report=array(); 
    $pathlist=PathList($id);
	
	if (!empty($pathlist)) {
		foreach($pathlist as $i=>$path) {
			$j=-1; //for multiple sites of biopsy, starts from 0
            $report[$i]['SpecimenGetDate']=$path['SpecimenGetDate'];
			$url='http://172.16.38.1/DigReport/Lab/PathReport.asp?PathCode='.$path['PathCode'];
			$dom=ntuhDom($url);
                
			foreach($dom->getElementsByTagName('td') as $td){
				if(mb_substr_count(trim($td->textContent),'器官描述','utf-8')==1){
				$j++;
				$report[$i][$j]['organ']=trim($td->previousSibling->previousSibling->textContent).', '.trim($td->nextSibling->nextSibling->textContent);
				}
				if(mb_substr_count(trim($td->textContent),'組織學診斷','utf-8')==1){
				$report[$i][$j]['diagnosis']=trim($td->nextSibling->nextSibling->textContent); 
				}
				if(mb_substr_count(trim($td->textContent),'檢查報告','utf-8')==1){
				$report[$i]['main']=trim($td->nextSibling->nextSibling->textContent);
				}
				if(mb_substr_count(trim($td->textContent),'補發報告','utf-8')==1){
				$report[$i]['ps']=trim($td->nextSibling->nextSibling->textContent);
				}
				//通常只有單一個'檢查報告'和'補發報告'
			}
		}
	} else {$report=NULL;}
		
	return $report;   //$report[$i][$j][''organ','diagnosis','main','ps']
  }    
  
  function ageOI($birthdate,$dateOI){ //Both in xxxx.xx.xx format; calculate the age until $dateOI. Return array consisting 'y' (yyyy), 'm', 'd'.
    $bd=explode('.',$birthdate);
    $DOIs=explode('.',$dateOI);
    $birthstamp=mktime(0,0,0,$bd[1],$bd[2],$bd[0]);
    $DOIstamp=mktime(0,0,0,$DOIs[1],$DOIs[2],$DOIs[0]);
    $age=$DOIstamp-$birthstamp;
    $y=floor($age/(365*24*3600));
    $m=floor(($age-$y*365*24*3600)/(30.5*24*3600));
    $d=ceil(($age-$y*365*24*3600-$m*30.5*24*3600)/(24*3600))+1;
    return array('y'=>$y,'m'=>$m,'d'=>$d);
  }

  function MDRD(){
    //Calculate MDRD estimation of GFR (integer)
    //注意：$name(from getName), $age(from ageOI), $cr(numeric value) 變數名稱需相同
    global $name, $age, $cr;
    if($name['gender']=='F'){
      $factor=0.742;
    }else $factor=1;
    $ageY=$age['y']+$age['m']/12+$age['d']/30.5;
    $GFR=186*pow($cr,-1.154)*pow($ageY,-0.203)*$factor;
    return round($GFR);
  }


  function PathRPT($pathcode){ 
      /* input: $pathcode
       * output: ($i=which time of pathology report)
       *         $report: [$i]['organ'],
       *                  [$i]['diagnosis'],
       *                  ['main'], ['ps'] 
       */
    $report=array();
    $i=-1;
    $url='http://172.16.38.1/DigReport/Lab/PathReport.asp?PathCode='.$pathcode;
    $dom=ntuhDom($url);
    foreach($dom->getElementsByTagName('td') as $td){
      if(mb_substr_count($td->textContent,'器官描述','utf-8')==1){
        $i++;
        $report[$i]['organ']=trim($td->previousSibling->previousSibling->textContent).', '.trim($td->nextSibling->nextSibling->textContent);
      }
      if(mb_substr_count($td->textContent,'組織學診斷','utf-8')==1)
        $report[$i]['diagnosis']=trim($td->nextSibling->nextSibling->textContent);
      if(mb_substr_count($td->textContent,'檢查報告','utf-8')==1)
        $report['main']=trim($td->nextSibling->nextSibling->textContent);
      if(mb_substr_count($td->textContent,'補發報告','utf-8')==1)
        $report['ps']=trim($td->nextSibling->nextSibling->textContent);
    }
    return $report;
  }

  $cka=get_session(); //Get cookie array for ALL HttpRequest
  $sessionid=portalsession();
  
?>
